package com.spzx.product.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.domain.Category;
import com.spzx.product.handler.CategoryExcelDataReadListener;
import com.spzx.product.mapper.CategoryMapper;
import com.spzx.product.service.CategoryService;
import io.jsonwebtoken.lang.Collections;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Resource
    @Lazy
    CategoryExcelDataReadListener categoryExcelDataReadListener;

    @Override
    public List<Category> listByPid(Long pid) {
        List<Category> categories = baseMapper.selectList(Wrappers.lambdaQuery(Category.class)
                .eq(Category::getParentId, pid)
                .orderByAsc(Category::getOrderNum));
        if (Collections.isEmpty(categories)) {
            return null;
        }

        //需要设置是否包含下一级  前端用来生成下一级图标
        categories.forEach(category -> {
            //使用正在遍历的分类的id当作父id查询下一级分类的数量
            category.setHasChildren(baseMapper.selectCount(Wrappers.lambdaQuery(Category.class)
                    .eq(Category::getParentId, category.getId())) > 0);
        });

        return categories;
    }

    @Override
    public boolean checkHasChildById(Long id) {
        boolean row = baseMapper.selectCount(Wrappers.lambdaQuery(Category.class)
                .eq(Category::getParentId, id)) > 0;
        if (row) {
            throw new RuntimeException("当前分类下有子分类，无法删除");
        }
        return true;
    }

    @Override
    public void exportCates(HttpServletResponse response) {
        try {
            //1、加载所有的分类数据
            List<Category> categories = this.list();
            //2、设置响应报文头：告诉浏览器如何解析响应体内容
            //如果需要在头中设置中文 必须使用Unicode编码处理
            String fileName = "商品分类_" +
                    new SimpleDateFormat("yyyy-MM-dd_HH_mm").format(new Date()) + ".xlsx";
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setHeader("content-Disposition", "attachment;filename=" + fileName);
            //3、通过EasyExcel将数据写入到excel文件中 设置到响应体
            EasyExcel.write(response.getOutputStream())
                    .sheet("商品分类")
                    .head(Category.class)
                    .doWrite(categories);
        } catch (IOException e) {
            throw new ServiceException("导出失败");
        }
    }


    @Override
    public boolean importCates(MultipartFile file) {
        //数据校验
        if (file.isEmpty()) {
            return false;
        }

        //数据校验： 文件名  必须是 csv  xls  xlsx
        String fileName = file.getOriginalFilename();
        if (!fileName.toLowerCase().endsWith(".csv") &&
                !fileName.toLowerCase().endsWith(".xls") &&
                !fileName.toLowerCase().endsWith(".xlsx")
        ){
            throw new ServiceException("文件格式不正确");
        }
        try {
            //1、为excel文件创建映射的实体类  直接使用Category
            //2、创建回调监听器  处理读取到的数据
            //3、读取数据
            EasyExcel.read(file.getInputStream())
                    .head(Category.class)
                    .registerReadListener(new CategoryExcelDataReadListener(this))
                    .doReadAll();
            return true;
        } catch (IOException e) {
            throw new ServiceException("商品分类导入失败");
        }
    }

    @Override
    public boolean cateExit(Category category) {
        LambdaQueryWrapper<Category> wrapper = Wrappers.lambdaQuery(Category.class);
        wrapper.eq(Category::getId, category.getId());
        wrapper.or(q->q.eq(Category::getParentId, category.getParentId())
                                .eq(Category::getName, category.getName()));

        return baseMapper.selectCount(wrapper)>0;
    }

    @Override
    public List<Category> listCatesTree() {
        //1、直接查询分类表所有数据
        List<Category> categories = this.list();

        //2、在业务中 组装数据
        //2.1 挑选1级分类集合
        List<Category> levelOneCates = categories.stream().filter(category -> category.getParentId().longValue() == 0l)
                .collect(Collectors.toList());
        buildCatesTree(levelOneCates , categories);
        //返回封装完成的一级分类
        return levelOneCates;
    }
    private void buildCatesTree(List<Category> parents, List<Category> categories) {
        if(CollectionUtils.isEmpty(parents) || CollectionUtils.isEmpty(categories)){
            return;
        }
        //2.2 遍历一级分类为它挑选他的下一级
        parents.forEach(parent -> {
            List<Category> children = categories.stream().filter(child -> child.getParentId().longValue() == parent.getId().longValue())
                    .collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(children)){
                parent.setChildren(children);
                //2.3 遍历二级分类 给它挑选三级
                buildCatesTree(children , categories);
            }
        });

    }
}
